#ifndef QNATIVECAMERA_H
#define QNATIVECAMERA_H

#include <QDeclarativeItem>
#include <QVideoFrame>
#include <QCamera>
#include <QCameraImageCapture>
#include <QMediaRecorder>

QT_USE_NAMESPACE

class VideoSurface;

// Observer design pattern to provide the view finder frame for the CustomCamera
// object.
class FrameObserver {
public:
    virtual bool updateFrame(const QVideoFrame &frame) = 0;
};

class QNativeCamera : public QDeclarativeItem, FrameObserver
{
    Q_OBJECT

    Q_ENUMS(State)

    // State properties
    Q_PROPERTY(State cameraState READ cameraState NOTIFY cameraStateChanged)

    // Devices properties
    Q_PROPERTY(QStringList availableDevices READ availableDevices)

    Q_PROPERTY(QString currentDevice READ currentDevice NOTIFY currentDeviceChanged)
    Q_PROPERTY(bool frontCamera READ frontCamera NOTIFY frontCameraChanged)
    Q_PROPERTY(bool preview READ preview WRITE setPreview)
    Q_PROPERTY(QSize resolution READ resolution WRITE setResolution NOTIFY resolutionChanged)
    Q_PROPERTY(qreal exposureCompensation  READ exposureCompensation  WRITE setExposureCompensation  NOTIFY exposureCompensationChanged)

public:

    enum State {
        ActiveState = QCamera::ActiveState,
        LoadedState = QCamera::LoadedState,
        UnloadedState = QCamera::UnloadedState
    };

    explicit QNativeCamera(QDeclarativeItem *parent = 0);
    ~QNativeCamera();

    QStringList availableDevices() const;

    virtual void paint(QPainter *painter,
                       const QStyleOptionGraphicsItem *option,
                       QWidget *widget);

    virtual bool updateFrame(const QVideoFrame &frame);

    QSize resolution();
    void setResolution(QSize& value);

    qreal exposureCompensation();
    void  setExposureCompensation(qreal);

    bool preview();
    void setPreview(bool value);

protected:
    void destroyResources();
    State cameraState() const;
    QString currentDevice() const;
    bool frontCamera() const;

signals:
    void resolutionChanged(QSize resolution);

    void digitalZoomChanged();
    void maximumDigitalZoomChanged();

    void exposureCompensationChanged();
    void exposureModeChanged();
    void supportedExposureModesChanged();

    void flashModeChanged();
    void supportedFlashModesChanged();

    void locked();
    void lockFailed();

    void isoValueChanged();
    void supportedIsoValuesChanged();

    void imageSaved(const QString &fileName);

    void cameraStateChanged();

    void whiteBalanceModeChanged();
    void supportedWhiteBalanceModesChanged();
    //void sharpeningLevelChanged();
    //void contrastChanged();

    void currentDeviceChanged();
    void frontCameraChanged();

    //void imageAnalyzerChanged();

public slots:
    void start(const QString &device);
    void stop();

    void cameraStateChanged(QCamera::State state);
    void handleImageSaved(int id, const QString &fileName);
    virtual void captureImage();
    virtual void imageAvailable(int,QVideoFrame);
    virtual void imageCaptured ( int id, const QImage & preview );
    virtual void imageExposed(int);

    void emitImageSavedSignal();

protected:
    qreal m_exposureCompensation;

    QCamera *m_camera; // Owned

    QString m_currentDevice;
    bool m_frontCamera;
    // Still image capturing
    QCameraImageCapture *m_cameraImageCapture; // Owned

    // Video capturing
    QMediaRecorder *m_mediaRecorder; // Owned

    // For showing view finder image
    VideoSurface *m_videoSurface; // Owned

    // For storing the latest frame
    unsigned int m_processedFrameCounter;
    unsigned int m_incomingFrameCounter;
    QImage m_imageFrame;
    QImage i_preview;
    bool m_preview;

    // File to be opened in the gallery.
    QString m_galleryImage;
    QSize m_resolution;
};

#endif // QNATIVECAMERA_H
